package br.unicamp.ic.inf312.arena.controle;

import br.unicamp.ic.inf312.arena.modelo.controleacesso.UsuarioSistema;
import br.unicamp.ic.inf312.arena.persistencia.dao.IUsuarioPerfilDAO;
import br.unicamp.ic.inf312.arena.util.I18nManager;
import br.unicamp.ic.inf312.framework.persistencia.DataAccessObjectFactory;

//TODO: Alteracao para a ativ. 2
//==============================================================
public class AutenticadorAcesso 
//==============================================================
{
	// DAO de usuarios
	private IUsuarioPerfilDAO daoUsuarios;
	
	// singleton
	private static AutenticadorAcesso _instance;
	
	// num. de tentativas de logon
	private byte tentativas;
	
	// num. maximo de tentativas permitidas para logon
	private static final byte MAX_TENTATIVAS = 3;
	
	
//	-------------------------------------------------
	private AutenticadorAcesso()
//	-------------------------------------------------
	{
		try
		{
			// recupera o DAO de usuarios
			this.daoUsuarios = (IUsuarioPerfilDAO) DataAccessObjectFactory.getImpl(IUsuarioPerfilDAO.class);
			
			// zera o numero de tentativas de logon			
			this.tentativas = 0;
		}		
		catch ( Exception exc )
		{
			exc.printStackTrace();
		}
	}
	
//	-------------------------------------------------
	public UsuarioSistema autenticarUsuario( UsuarioSistema usuario ) 
		throws AutenticacaoException
//	-------------------------------------------------
	{
		try
		{
			// verifica se o num. maximo de tentativas ja foi atingido
			if ( AutenticadorAcesso.MAX_TENTATIVAS <= this.tentativas )
				//TODO: Alteracao para a ativ. 3
				throw new MaxTentativasException( 
						I18nManager.getInstance().getPropriedadeString("menu.dialogo.logon.erro.maxtentativas"));

			// tenta autenticar o usuario
			UsuarioSistema usuarioAut = this.daoUsuarios.validarLogon( usuario );
			
			// verifica se o logon foi autenticado com sucesso
			if ( null == usuarioAut )
				//TODO: Alteracao para a ativ. 3
				throw new LogonInvalidoException( 
						I18nManager.getInstance().getPropriedadeString("menu.dialogo.logon.erro.logininvalido"));
			
			// retorna o usuario autenticado
			return ( usuarioAut );
		}
		catch ( AutenticacaoException aut )
		{
			// relanca a excecao
			throw aut;
		}
		catch ( Exception exc )
		{
			// lanca uma excecao "generica" de autenticacao
			throw new AutenticacaoException( exc.getMessage() );
		}
		finally
		{
			// incrementa o numero de tentativas de logon
			this.tentativas = (byte) Math.min( AutenticadorAcesso.MAX_TENTATIVAS, ++this.tentativas );
		}
	}
	
//	-------------------------------------------------
	public static AutenticadorAcesso getInstance()
//	-------------------------------------------------
	{
		// verifica se a instancia do singleton ja foi inicializada
		if ( null == _instance )
			_instance = new AutenticadorAcesso();
		
		return ( _instance );
	}
}
